<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <title></title>
</head>

<body>
  <div id="app">

  </div>
  <script>
    var data = {
      name: "django",
      age: 29
    }

    //data.a  data.a.b?   递归
    function walk(data) {
      for (let key in data) {
        let deps = []; //存储依赖 
        let val = data[key];
        var nativeString = toString.call(val);
        if (nativeString === "[object Object]") {
          walk(val);
        }
        Object.defineProperty(data, key, {
          get: function () {
            //收集依赖
            deps.push(target);
            return val;
          },
          set: function (newval) {
            if (val === newval) {
              return
            };
            val = newval;
            //重置值的时候  触发我之前收集的依赖
            deps.forEach(function (fn) {
              fn();
            })
          }
        })
      }
    }
    walk(data);

    var target = null;

    //a.b  => [a][b]
    function $watch(key, fn) {
      target = fn;
      var arr, obj = data;
      if (typeof key === "function") {
        key();
        return;
      }
      if (/\./.test(key)) {
        arr = key.split(".");
        arr.forEach(function (name) {  //{b:1}
          obj = obj[name];  //data.a.b
        })
        return;
      }
      data[key]; //data[a][b]
    }

    //渲染函数
    function render() {
      return document.write("姓名: " + data.name + "年龄: " + data.age);
    }

    $watch(render, render);  //收集的依赖

    data.name = "star";


  </script>
</body>

</html>